﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data.SqlClient;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace milanov
{
    //Eden
    public partial class Download : System.Web.UI.Page
    {
        //hiermee haal je de userid op doormiddel van een query
        private Guid UserId
        {
            get
            {
                return Cartclass.getUserID(User.Identity.Name);
            }
        }
        protected void Page_Load(object sender, EventArgs e)
        {
            //deze code haalt de query string op uit het url en kijkt als het leeg is of niet.
            if (Request.QueryString["id"] != null)
            {
                //Deze code controleert als de huidige gebruiker daadwerkelijk voor de foto heeft betaald, en als er niet voor betaald is dan
                if (Controleer(Convert.ToInt32(Request.QueryString["id"])))
                {
                   //dit zorgt ervoor dat we met de photoid met behulp van een query de filenaam uit het de database haalt
                   string filename = GetFileName(Convert.ToInt32(Request.QueryString["id"]));
                   //hiermee halen we de normale naam van de foto uit het database
                   string name = GetName(Convert.ToInt32(Request.QueryString["id"]));
                   //hiermee kan je spaties verplaatsen met '_' in de naam, dit is om errors te voorkomen
                   name = name.Replace(" ", "_");
                   //dit roept een decrypt methode aan om de foto file te decrypten uit het "secret" mapje, en het echte bestand wordt dan tijdelijk opgeslagen in "real"
                   DecryptFile(Server.MapPath("~/Pictures/secret/" + filename + "E"), Server.MapPath("~/Pictures/real/" + filename), "1234512345678976");
                   //dit geeft aan dat de type wat gedownload wordt een jpeg/jpg bestandje is
                   Response.ContentType = "image/jpeg";
                   //dit zorgt ervoor dat de filename die gedownload wordt de normale naam krijgt die in de database staat
                   Response.AppendHeader("Content-Disposition", "attachment; filename=" +name +".jpg");
                   //hiermee wordt de download gestart en het file geselecteert
                   Response.TransmitFile(Server.MapPath("~/Pictures/real/" + filename));
                   //¿?
                   Response.Flush();
                   //File wort direct gedelete zodra de download wordt geaccepteert
                   if (File.Exists(Server.MapPath("~/Pictures/real/" + filename)))
                   {
                       File.Delete(Server.MapPath("~/Pictures/real/" + filename));
                   }
                   //Download is klaar en wordt stop gezet.
                   Response.End();
                   


                }
            }
        }
        // een methode die controleert of de user de foto die hij wilt downloaden daadwerelijk gekocht heeft of niet.
        bool Controleer(int id)
        {
            using (SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["fotosDB"].ConnectionString))
            {
                bool go;
                string query = "select o.Completed from Orders o, Cart c where o.OrderId = c.OrderId AND c.PhotoId = @photoid AND o.UserId = @userid;";
                using (SqlDataAdapter da = new SqlDataAdapter(query, con))
                {
                    SqlCommand showresult = new SqlCommand(query, con);
                    showresult.Parameters.AddWithValue("photoid", id);
                    showresult.Parameters.AddWithValue("userid", UserId);

                    con.Open();
                    go = Convert.ToBoolean(showresult.ExecuteScalar());
                    con.Close();
                }
                return go;
            }
        }
        //een methode die de filename van de opgevraagde foto uit de database haalt
        string GetFileName(int id)
        {
            using (SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["fotosDB"].ConnectionString))
            {
                string filename;
                string query = "SELECT [Filename] FROM [Fotos] where FileID = @fileid;";
                using (SqlDataAdapter da = new SqlDataAdapter(query, con))
                {
                    SqlCommand showresult = new SqlCommand(query, con);
                    showresult.Parameters.AddWithValue("fileid", id);

                    con.Open();
                    filename = Convert.ToString(showresult.ExecuteScalar());
                    con.Close();
                }
                return filename;
            }
        }
        // een emthode die de normale naam van de opgevraagde foto uit de database haalt
        string GetName(int id)
        {
            using (SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["fotosDB"].ConnectionString))
            {
                string name;
                string query = "select name from fotos where fileid = @fileid;";
                using (SqlDataAdapter da = new SqlDataAdapter(query, con))
                {
                    SqlCommand showresult = new SqlCommand(query, con);
                    showresult.Parameters.AddWithValue("fileid", id);

                    con.Open();
                    name = Convert.ToString(showresult.ExecuteScalar());
                    con.Close();
                }
                return name;
            }
        }
        //een methode die ervoor zorgt dat de file gedecrypt wordt
        void DecryptFile(string inputFile, string outputFile, string skey)
        {
            try
            {
                using (RijndaelManaged aes = new RijndaelManaged())
                {
                    byte[] key = ASCIIEncoding.UTF8.GetBytes(skey);

                    
                    byte[] IV = ASCIIEncoding.UTF8.GetBytes(skey);

                    using (FileStream fsCrypt = new FileStream(inputFile, FileMode.Open))
                    {
                        using (FileStream fsOut = new FileStream(outputFile, FileMode.Create))
                        {
                            using (ICryptoTransform decryptor = aes.CreateDecryptor(key, IV))
                            {
                                using (CryptoStream cs = new CryptoStream(fsCrypt, decryptor, CryptoStreamMode.Read))
                                {
                                    int data;
                                    while ((data = cs.ReadByte()) != -1)
                                    {
                                        fsOut.WriteByte((byte)data);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            catch
            {
                Console.WriteLine("Decryption failed");
                Console.ReadKey();
            }
        }
    }
}